package com.sudo.service.admin.service.impl;

import com.sudo.common.enums.SysStatus;
import com.sudo.common.constant.UserConstant;
import com.sudo.common.utils.LocalDateTimeUtil;
import com.sudo.dao.admin.entity.SysButton;
import com.sudo.dao.admin.entity.SysRoleButton;
import com.sudo.dao.admin.entity.SysRoleMenu;
import com.sudo.dao.admin.mapper.SysButtonMapper;
import com.sudo.dao.admin.mapper.SysMenuMapperCustom;
import com.sudo.dao.admin.mapper.SysRoleButtonMapper;
import com.sudo.dao.admin.model.bo.SysButtonBO;
import com.sudo.service.admin.service.SysButtonService;
import com.sudo.service.admin.service.AdminBaseService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;

/**
 *
 * @author 为道日损 2020-04-28 8:37
 * webSite：https://www.sudo.ren
 */
@Service
public class SysButtonServiceImpl extends AdminBaseService implements SysButtonService {

    @Resource
    private SysButtonMapper sysButtonMapper;

    @Resource
    private SysRoleButtonMapper sysRoleButtonMapper;

    @Resource
    private SysMenuMapperCustom sysMenuMapperCustom;

    /**
     *通过菜单code获取对应的简单版button
     * @param menuCode 菜单code
     * @return list
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public List<SysButton> getSimpleButtonByMenuCode(String menuCode) {
        Example example = new Example(SysButton.class);
        example.selectProperties("bName", "bCode", "menuCode", "status");
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuCode", menuCode);
        return sysButtonMapper.selectByExample(example);
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public SysButton getSysButtonByMenuButtonCode(String menuCode, String buttonCode) {
        Example example = new Example(SysButton.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuCode", menuCode);
        criteria.andEqualTo("bCode", buttonCode);
        return sysButtonMapper.selectOneByExample(example);
    }

    /**
     * 通过菜单code获取对应的button
     * @param menuCode menuCode
     * @return list
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public List<SysButton> getSysButtonByMenuCode(String menuCode) {
        Example example = new Example(SysButton.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuCode", menuCode);

        return sysButtonMapper.selectByExample(example);
    }

    /**
     * 修改button
     * @param sysButtonBO sysButtonBO
     * @param sessionUser 当前session用户
     * @return int
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int updateSysButtonByMenuButtonCode(SysButtonBO sysButtonBO, String sessionUser) {
        //查询原始数据
        SysButton oldSysButton = getSysButtonByMenuButtonCode(
                sysButtonBO.getMenuCode(), sysButtonBO.getbCode());


        Example example = new Example(SysButton.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuCode", sysButtonBO.getMenuCode());
        criteria.andEqualTo("bCode",sysButtonBO.getbCode());

        SysButton sysButton = new SysButton();
        BeanUtils.copyProperties(sysButtonBO, sysButton,"menuCode","buttonCode");
        sysButton.setUpdateBy(sessionUser);
        String now = LocalDateTimeUtil.getStandardDateTimeStr();
        sysButton.setUpdateTime(now);
        if (!SysStatus.ON.name().equals(sysButton.getStatus())) {
            sysButton.setStatus(SysStatus.OFF.name());
        }
        boolean isEqual = oldSysButton.getStatus().equals(sysButtonBO.getStatus());
        int affectCount = sysButtonMapper.updateByExampleSelective(sysButton, example);

        //====== redis ======
        // redis_menu_button (更新按钮)
        // redis_role_permission (更新可用角色-可用菜单-可用按钮)
        if (!isEqual && affectCount > 0) {
            List<SysRoleMenu> sysRoleMenuList = sysMenuMapperCustom.getRoleMenuByMenuCodeAndRoleStatus(
                    sysButtonBO.getMenuCode(), SysStatus.ON.name());
            if (SysStatus.ON.name().equals(sysButtonBO.getStatus())) {
                //on
                ////setRedisMenuButtonToRedis(sysButtonBO.getMenuCode(), sysButtonBO.getbCode());
                for (SysRoleMenu rm : sysRoleMenuList) {
                    setRedisRolePermissionToRedis(rm.getRoleCode(),rm.getMenuCode(),sysButtonBO.getbCode());
                }
            } else {
                //off
                //// delRedisMenuButtonFromRedis(sysButtonBO.getMenuCode(), sysButtonBO.getbCode());
                for (SysRoleMenu rm : sysRoleMenuList) {
                    delRedisRolePermissionFromRedis(rm.getRoleCode(),rm.getMenuCode(),sysButtonBO.getbCode());
                }
            }
        }
        return affectCount;
    }

    /**
     * 给菜单新增button
     * @param sysButtonBO sysButtonBO
     * @param sessionUser 当前session用户
     * @return int
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int addSysButton(SysButtonBO sysButtonBO, String sessionUser) {
        SysButton sysButton = new SysButton();
        BeanUtils.copyProperties(sysButtonBO,sysButton);
        sysButton.setCreateBy(sessionUser);
        String now = LocalDateTimeUtil.getStandardDateTimeStr();
        sysButton.setCreateTime(now);

        //给超级管理员添加权限
        SysRoleButton sysRoleButton = new SysRoleButton();
        sysRoleButton.setRoleCode(UserConstant.SUPER_ADMIN);
        sysRoleButton.setMenuCode(sysButton.getMenuCode());
        sysRoleButton.setButtonCode(sysButton.getbCode());
        sysRoleButtonMapper.insertSelective(sysRoleButton);

        int affectCount = sysButtonMapper.insertSelective(sysButton);

        // ====== redis ======
        if (affectCount > 0 && SysStatus.ON.name().equals(sysButtonBO.getStatus())) {
            // redis_menu_button (新增可用菜单-可用按钮)
            setRedisMenuButtonToRedis(sysButton.getMenuCode() ,sysButton.getbCode());

            // redis_role_permission (新增超级管理员权限)
            setRedisRolePermissionToRedis(
                    UserConstant.SUPER_ADMIN,
                    sysButton.getMenuCode(),
                    sysButton.getbCode()
            );
        }
        return affectCount;
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int deleteSysButtonByMenuButtonCode(String menuCode, String buttonCode) {
        Example example = new Example(SysButton.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuCode", menuCode);
        criteria.andEqualTo("bCode", buttonCode);

        //删除角色-菜单-按钮关联关系
        Example example1 = new Example(SysRoleButton.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("buttonCode", buttonCode);
        criteria1.andEqualTo("menuCode", menuCode);
        sysRoleButtonMapper.deleteByExample(example1);

        int affectCount = sysButtonMapper.deleteByExample(example);

        //====== redis ======
        // redis_menu_button (删除可用菜单-可用按钮)
        // redis_role_permission (删除可用角色-可用菜单-可用按钮)
        if (affectCount > 0) {
            //// delRedisMenuButtonFromRedis(menuCode,buttonCode);
            List<SysRoleButton> sysRoleButtonList = getRoleButtonByMenuButtonCode(menuCode, buttonCode);
            for (SysRoleButton rb :sysRoleButtonList) {
                delRedisRolePermissionFromRedis(rb.getRoleCode(), rb.getMenuCode(), rb.getButtonCode());
            }
        }

        return affectCount;
    }

    /**
     * 判断buttonCode是否存在
     * @param buttonCode buttonCode
     * @return boolean
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public boolean isButtonCodeExist(String menuCode ,String buttonCode) {
        Example example = new Example(SysButton.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("bCode", buttonCode);
        criteria.andEqualTo("menuCode", menuCode);
        List<SysButton> sysButtonList = sysButtonMapper.selectByExample(example);
        return !CollectionUtils.isEmpty(sysButtonList);
    }

    /**
     * 根据角色code获取对应权限的按钮
     * @param roleCode 角色code
     * @return list
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public List<SysRoleButton> getButtonCodeByRoleMenuCode(String roleCode ,String menuCode) {
        Example example = new Example(SysRoleButton.class);
        example.selectProperties("roleCode","buttonCode","menuCode");
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleCode",roleCode);
        criteria.andEqualTo("menuCode",menuCode);
        return sysRoleButtonMapper.selectByExample(example);
    }

    /**
     * 根据menuButtonCode 获取SysRoleButton
     * @param menuCode 菜单code
     * @param buttonCode 按钮code
     * @return list
     */
    @Override
    public List<SysRoleButton> getRoleButtonByMenuButtonCode(String menuCode, String buttonCode) {
        Example example = new Example(SysRoleButton.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuCode", menuCode);
        criteria.andEqualTo("buttonCode", buttonCode);
        return sysRoleButtonMapper.selectByExample(example);
    }


}
